
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.apache.http.HttpResponse;

import com.dropbox.client.DropboxClient;
import com.dropbox.client.DropboxException;

/**
 * FileLoader reads the specified files from Dropbox under the specified path
 * and then notifies Stylepad to update
 * @author g0900398
 *
 */
public class FileLoader extends Thread {
	
	//DropboxClient dbClient; //removed u099048h
	String root;	// "sandbox"
	String path;	// a path should be of the form "/testpath"
	ArrayList<String> modifiedFiles;
	
	//added u099048h
	SecurityHandler securityHandler;
	private static SubFileHandler subFile;

	SmartManager sm;// only for telling SmartManager to update the loaded in files
	
	public FileLoader(SecurityHandler secHandler, String root, String path, ArrayList<String> names, SmartManager sm){
		//changed u099048h
		//this.dbClient = client;
		this.securityHandler = secHandler;
		
		this.root = root;
		this.path = path;
		this.modifiedFiles = names;
		this.sm = sm;
		this.subFile = new SubFileHandler();
	}
	
	public void run(){

		/**
		 * connect to Dropbox, read the files specified in updatedFileNames, and then
		 * combine these files into a Document, notify Stylepad to update its document
		 */
		synchronized(Stylepad.loading){
			
			final ArrayList<Document> doc = new ArrayList<Document>();
			final ArrayList<String> filenames = new ArrayList<String>();
			
			for(int i = 0; i < modifiedFiles.size(); i++){
				HttpResponse resp = null;
				
				//changed u099048h
				//resp = dbClient.getFile(root, path + "/" + modifiedFiles.get(i));
				resp = securityHandler.getFile(modifiedFiles.get(i));
				
				Statistics.downloadRequest ++;
				System.out.println("FL##!@ Add 1 to download request.");
				
				if(resp == null){
					System.out.println("Invalid response for request: " + i);
					continue;
				}
				int status = resp.getStatusLine().getStatusCode();
				if(status != 200){
					System.out.println("Invalid status code for request: " + i + " " + status);
					continue;
				}
				
				//ADDED BY U099048H
				String filename = modifiedFiles.get(i);
				
				try {	
					InputStream in = resp.getEntity().getContent();		
					OutputStream out = new FileOutputStream("msub_file"+filename);
					
					int numRead = 0;
					byte[] buf = new byte[1024];
					
					while ((numRead = in.read(buf)) >= 0){
						out.write(buf, 0, numRead);
					}
					
					out.close();
					in.close();
					
					String unlockedName = new String();
					if(SDAction.isFileLocked (filename))
						unlockedName = SDAction.renameFromLockToUnlock (filename);
					else
						unlockedName = filename;
					
					InputStream in2 = new FileInputStream("msub_file"+filename);	
					System.out.println(filename);
					
					if (!subFile.subFileHMACCheck(in2, unlockedName)){
						//print some error
				
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
				try {
					InputStream in3 = new FileInputStream("msub_file" + filename);	
					if (!subFile.decryptSubFile(in3, "d_msub_file" + filename)){
						//print some error
				
					}
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
						
					
					//*******************************************************************//	
				File en_file = new File("msub_file" + filename);
				File d_file = new File("d_msub_file" + filename);
				
				try{	
					ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d_msub_file" + filename));
					Document tmpdoc = (Document)ois.readObject();	
					// remove the end of document character
					tmpdoc.remove(tmpdoc.getLength()-1, 1);
					// check if the file is locked or not
					/*if(SDAction.isFileLocked(modifiedFiles.get(i))){

				    	//((DefaultStyledDocument) tmpdoc).setCharacterAttributes(0, tmpdoc.getLength(), SmartManager.otherLockAttr, false);
						sm.drawLockByOtherHighlight (0);
					}*/
										
					doc.add(tmpdoc);
					filenames.add(modifiedFiles.get(i));
					
					ois.close();
					en_file.delete();
					d_file.delete();

				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}catch (BadLocationException e) {
				// TODO Auto-generated catch block
					e.printStackTrace();
				}
						
			}
			
			if(!doc.isEmpty()){
				//System.out.println(doc.size());
				SwingUtilities.invokeLater(new Runnable(){public void run(){

					sm.updateNotification(doc, filenames, 1);
				}});

				
			}
			
		}

	}
	
	
	
}

